const { dataFormatError } = require("../constant/error.type");

/**
 * 通用参数校验中间件生成函数
 * @param {Object} rules - 参数校验规则对象，键为参数名，值为校验规则
 *   规则格式支持：
 *   - 基础类型简写：'int'（必传整数）、'int?'（可选整数）、'string'（必传字符串）等
 *   - 完整配置对象：{ type: 'number', required: true, min: 1 } 等
 *   详细规则参考：https://github.com/node-modules/parameter
 * @param {Object} errorInfo - 自定义错误信息对象（用于统一错误处理）
 *   以 dataFormatError 为默认值，不传递该参数时默认值生效
 *   需包含错误处理所需的基础属性（如错误码、错误提示等，具体结构由全局错误处理器定义）
 *   示例：{ code: 400, message: '参数格式错误', result: null }
 * @returns {Function} Koa中间件函数，用于校验请求体参数
 *
 * 功能说明：
 * 1. 通过闭包保存校验规则和错误信息对象，生成可复用的参数校验中间件
 * 2. 使用koa-parameter的verifyParams同步方法执行校验（校验ctx.request.body中的参数）
 * 3. 校验失败时：
 *    - 将具体错误信息挂载到errorInfo.result属性
 *    - 触发全局错误事件，由全局错误处理器统一返回格式化响应
 * 4. 校验通过则调用next()进入下一个中间件
 *
 * 示例：
 *   // 定义购物车相关的错误信息对象
 *   const cartFormatError = { code: 400, message: '购物车参数错误', result: null };
 *   // 校验购物车商品ID必须为数字
 *   validatorParams({ goods_id: 'int' }, cartFormatError)
 *   // 校验数量为可选整数，且最小值为1
 *   validatorParams({
 *     number: { type: 'int', required: false, min: 1 }
 *   }, cartFormatError)
 */
const validatorParams = (rules, errorInfo = dataFormatError) => {
  return async (ctx, next) => {
    try {
      /**
       * 调用koa-parameter提供的verifyParams同步方法校验请求体参数
       * 该方法会自动检查ctx.request.body中的参数是否符合rules定义的规则
       * 若不符合则抛出包含错误信息的异常
       */
      ctx.verifyParams(rules);
    } catch (error) {
      // 绑定错误信息到自定义错误对象
      errorInfo.result = error;
      // 触发全局错误事件，由全局错误处理器统一处理
      return ctx.app.emit("error", errorInfo, ctx);
    }
    await next();
  };
};

module.exports = { validatorParams };
